package cz.vutbr.fit.dnacompress.encoding;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.biojava.utils.ParserException;

import com.mellowtech.disc.BitVector;

import cz.vutbr.fit.dnacompress.events.AlignEvent;

/**
 * Coder Elias-Delta kodu
 */
public class EliasCoder extends AbstractCoder {
	
	public EliasCoder(String countTableFileName) throws IOException, ParserException {
		
		setCountTables( countTableFileName);
		this.coderID = 2;
	}

	@Override
	public List<AlignEvent> decode( InputStream is) throws IOException, ParserException {
		
		// buffer pro cteni dat
		ByteBuffer byteBuffer = ByteBuffer.allocate( 100);
		int r;
		while((r = is.read()) != -1) {
			byteBuffer.put((byte) r);
		}
		byteBuffer.rewind();
		
		// elias vektor
		BitVector bv = new BitVector();
		bv.fromBytes( byteBuffer);
		bv.reset();
		
		// vytvoreni eventu z dat (pozice, data, pozice, data)
		List<AlignEvent> events = new ArrayList<AlignEvent>();
		int digit = 0;
		int position = 0;
		boolean switcher = true;
		while( (digit = bv.getDelta()) != -1) {
			
			AlignEvent event = null;
			if( switcher) {
				
				position = digit;
			} else {
				
				event = AlignEvent.getClassWithData( countTableDecode.get( digit));			
				event.setPosition( position);
				events.add( event);
			}
			switcher = !switcher;
			
		}
		return events;
	}

	@Override
	public byte[] encode(List<AlignEvent> events) {
		
		// Elias vektor
		BitVector bv = new BitVector();		
		// zakodovani eventu do vektoru
		for( Iterator<AlignEvent> i = events.iterator(); i.hasNext();) {
			
			AlignEvent event = i.next();
			int position = event.getPosition();
			// first encode position
			bv.putDelta( position);
			// second encode data
			int codeTableOffset = countTableEncode.get( event.getCountID()); 
			bv.putDelta( codeTableOffset);
		}
		
		return bv.toBytes().array();
	}
	
	public String toString() {
		return "Elias coder";
	}

}
